<!DOCTYPE html>
<html lang="en-US">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>C++98核心详解 | whoway</title>
    <meta name="description" content="Personal Blog Website">
    <link rel="icon" href="/images/photo.jpg">
  <link rel="manifest" href="/images/photo.jpg">
  <link rel="apple-touch-icon" href="/images/photo.jpg">
  <meta http-quiv="pragma" cotent="no-cache">
  <meta http-quiv="pragma" cotent="no-cache,must-revalidate">
  <meta http-quiv="expires" cotent="0">
    
    <link rel="preload" href="/assets/css/0.styles.0dbae9ec.css" as="style"><link rel="preload" href="/assets/js/app.c70e21ad.js" as="script"><link rel="preload" href="/assets/js/2.570d8a23.js" as="script"><link rel="prefetch" href="/assets/js/10.15222a53.js"><link rel="prefetch" href="/assets/js/100.7e0e5a86.js"><link rel="prefetch" href="/assets/js/101.efd59f25.js"><link rel="prefetch" href="/assets/js/102.dfbdc06c.js"><link rel="prefetch" href="/assets/js/103.d3ab2109.js"><link rel="prefetch" href="/assets/js/104.117957ef.js"><link rel="prefetch" href="/assets/js/105.046e8ff3.js"><link rel="prefetch" href="/assets/js/106.aebdc17d.js"><link rel="prefetch" href="/assets/js/107.248733c2.js"><link rel="prefetch" href="/assets/js/108.a2fecadc.js"><link rel="prefetch" href="/assets/js/109.35196857.js"><link rel="prefetch" href="/assets/js/11.770642f2.js"><link rel="prefetch" href="/assets/js/110.cf3d973c.js"><link rel="prefetch" href="/assets/js/111.f985889a.js"><link rel="prefetch" href="/assets/js/112.ad614f41.js"><link rel="prefetch" href="/assets/js/113.f666653c.js"><link rel="prefetch" href="/assets/js/114.c6c3f384.js"><link rel="prefetch" href="/assets/js/115.e51d3c2f.js"><link rel="prefetch" href="/assets/js/116.4f4b39f5.js"><link rel="prefetch" href="/assets/js/117.99352e11.js"><link rel="prefetch" href="/assets/js/118.c6ae6572.js"><link rel="prefetch" href="/assets/js/119.4ccbe778.js"><link rel="prefetch" href="/assets/js/12.042a92ff.js"><link rel="prefetch" href="/assets/js/120.edda1c4f.js"><link rel="prefetch" href="/assets/js/121.30a638ed.js"><link rel="prefetch" href="/assets/js/122.6efcefb1.js"><link rel="prefetch" href="/assets/js/123.91e6665b.js"><link rel="prefetch" href="/assets/js/124.f27e3d7e.js"><link rel="prefetch" href="/assets/js/125.c75712d5.js"><link rel="prefetch" href="/assets/js/126.ed756cce.js"><link rel="prefetch" href="/assets/js/127.2f06c74c.js"><link rel="prefetch" href="/assets/js/128.d5f6f30e.js"><link rel="prefetch" href="/assets/js/129.508b7eed.js"><link rel="prefetch" href="/assets/js/13.b5280c37.js"><link rel="prefetch" href="/assets/js/130.dc05f9aa.js"><link rel="prefetch" href="/assets/js/131.e0ba69b1.js"><link rel="prefetch" href="/assets/js/132.d79bcaa4.js"><link rel="prefetch" href="/assets/js/133.34acc01a.js"><link rel="prefetch" href="/assets/js/134.dabf64d5.js"><link rel="prefetch" href="/assets/js/135.ad90c915.js"><link rel="prefetch" href="/assets/js/136.dbb0074f.js"><link rel="prefetch" href="/assets/js/137.284ad365.js"><link rel="prefetch" href="/assets/js/138.a4b6856f.js"><link rel="prefetch" href="/assets/js/139.c9c1e20f.js"><link rel="prefetch" href="/assets/js/14.df02ba38.js"><link rel="prefetch" href="/assets/js/140.8b0a9269.js"><link rel="prefetch" href="/assets/js/141.9c7759c5.js"><link rel="prefetch" href="/assets/js/142.a4201a82.js"><link rel="prefetch" href="/assets/js/143.d7da6e8c.js"><link rel="prefetch" href="/assets/js/144.5e48e65d.js"><link rel="prefetch" href="/assets/js/145.a0e2633c.js"><link rel="prefetch" href="/assets/js/146.3c775f9b.js"><link rel="prefetch" href="/assets/js/147.22add89a.js"><link rel="prefetch" href="/assets/js/148.cfde1009.js"><link rel="prefetch" href="/assets/js/149.ffc835b5.js"><link rel="prefetch" href="/assets/js/15.fbdfc4ee.js"><link rel="prefetch" href="/assets/js/150.406c4b20.js"><link rel="prefetch" href="/assets/js/151.b2040eea.js"><link rel="prefetch" href="/assets/js/152.7bc65661.js"><link rel="prefetch" href="/assets/js/153.1d7c65e3.js"><link rel="prefetch" href="/assets/js/154.1309de49.js"><link rel="prefetch" href="/assets/js/155.81d3ee1f.js"><link rel="prefetch" href="/assets/js/156.154a4ef2.js"><link rel="prefetch" href="/assets/js/16.e5eb6147.js"><link rel="prefetch" href="/assets/js/17.57853c4a.js"><link rel="prefetch" href="/assets/js/18.cb9d7518.js"><link rel="prefetch" href="/assets/js/19.f354dc47.js"><link rel="prefetch" href="/assets/js/20.b5af7fad.js"><link rel="prefetch" href="/assets/js/21.0b1928fe.js"><link rel="prefetch" href="/assets/js/22.f78666de.js"><link rel="prefetch" href="/assets/js/23.29c3f366.js"><link rel="prefetch" href="/assets/js/24.6f596516.js"><link rel="prefetch" href="/assets/js/25.14067b60.js"><link rel="prefetch" href="/assets/js/26.74ba4989.js"><link rel="prefetch" href="/assets/js/27.13d60edd.js"><link rel="prefetch" href="/assets/js/28.9523cb32.js"><link rel="prefetch" href="/assets/js/29.8ec842e9.js"><link rel="prefetch" href="/assets/js/3.3fb3d2e0.js"><link rel="prefetch" href="/assets/js/30.805597a8.js"><link rel="prefetch" href="/assets/js/31.831b195d.js"><link rel="prefetch" href="/assets/js/32.063c672d.js"><link rel="prefetch" href="/assets/js/33.6d93fac3.js"><link rel="prefetch" href="/assets/js/34.56e8263c.js"><link rel="prefetch" href="/assets/js/35.dbe688bb.js"><link rel="prefetch" href="/assets/js/36.dc5af2c1.js"><link rel="prefetch" href="/assets/js/37.0a7494f6.js"><link rel="prefetch" href="/assets/js/38.fe4fc171.js"><link rel="prefetch" href="/assets/js/39.f5ed5e92.js"><link rel="prefetch" href="/assets/js/4.2c405ec8.js"><link rel="prefetch" href="/assets/js/40.fe7e2714.js"><link rel="prefetch" href="/assets/js/41.30b0811d.js"><link rel="prefetch" href="/assets/js/42.76f52d62.js"><link rel="prefetch" href="/assets/js/43.e7bb0817.js"><link rel="prefetch" href="/assets/js/44.ead0e883.js"><link rel="prefetch" href="/assets/js/45.235df046.js"><link rel="prefetch" href="/assets/js/46.5f09e829.js"><link rel="prefetch" href="/assets/js/47.67116354.js"><link rel="prefetch" href="/assets/js/48.31f34543.js"><link rel="prefetch" href="/assets/js/49.10b5ebba.js"><link rel="prefetch" href="/assets/js/5.6f47322c.js"><link rel="prefetch" href="/assets/js/50.c0f0b7f1.js"><link rel="prefetch" href="/assets/js/51.5143f3bf.js"><link rel="prefetch" href="/assets/js/52.eeddfd48.js"><link rel="prefetch" href="/assets/js/53.eb790db5.js"><link rel="prefetch" href="/assets/js/54.8fe5421c.js"><link rel="prefetch" href="/assets/js/55.d8f9004b.js"><link rel="prefetch" href="/assets/js/56.62ac9b92.js"><link rel="prefetch" href="/assets/js/57.a9caec0d.js"><link rel="prefetch" href="/assets/js/58.f93fc522.js"><link rel="prefetch" href="/assets/js/59.a81a03aa.js"><link rel="prefetch" href="/assets/js/6.8c2ea393.js"><link rel="prefetch" href="/assets/js/60.ab782775.js"><link rel="prefetch" href="/assets/js/61.6dd12daf.js"><link rel="prefetch" href="/assets/js/62.76f4b01f.js"><link rel="prefetch" href="/assets/js/63.6f8a4742.js"><link rel="prefetch" href="/assets/js/64.6f8bb1fa.js"><link rel="prefetch" href="/assets/js/65.4120a44b.js"><link rel="prefetch" href="/assets/js/66.360c2d2b.js"><link rel="prefetch" href="/assets/js/67.26f84d32.js"><link rel="prefetch" href="/assets/js/68.68f45e5e.js"><link rel="prefetch" href="/assets/js/69.e311eb56.js"><link rel="prefetch" href="/assets/js/7.6762b2d7.js"><link rel="prefetch" href="/assets/js/70.cea82674.js"><link rel="prefetch" href="/assets/js/71.783ddcf7.js"><link rel="prefetch" href="/assets/js/72.e5467385.js"><link rel="prefetch" href="/assets/js/73.b8fb681b.js"><link rel="prefetch" href="/assets/js/74.1bae37db.js"><link rel="prefetch" href="/assets/js/75.024387e5.js"><link rel="prefetch" href="/assets/js/76.a8e53010.js"><link rel="prefetch" href="/assets/js/77.8c55500a.js"><link rel="prefetch" href="/assets/js/78.7ce90bf5.js"><link rel="prefetch" href="/assets/js/79.ef71713f.js"><link rel="prefetch" href="/assets/js/8.788a6364.js"><link rel="prefetch" href="/assets/js/80.acad589d.js"><link rel="prefetch" href="/assets/js/81.02670d10.js"><link rel="prefetch" href="/assets/js/82.53b7b1ac.js"><link rel="prefetch" href="/assets/js/83.99eb8581.js"><link rel="prefetch" href="/assets/js/84.d1535ce3.js"><link rel="prefetch" href="/assets/js/85.fe2b7de9.js"><link rel="prefetch" href="/assets/js/86.41850272.js"><link rel="prefetch" href="/assets/js/87.1cdc6df9.js"><link rel="prefetch" href="/assets/js/88.01bf3461.js"><link rel="prefetch" href="/assets/js/89.17c69819.js"><link rel="prefetch" href="/assets/js/9.3813842d.js"><link rel="prefetch" href="/assets/js/90.f6ae7e35.js"><link rel="prefetch" href="/assets/js/91.507bc284.js"><link rel="prefetch" href="/assets/js/92.90551782.js"><link rel="prefetch" href="/assets/js/93.dc442d78.js"><link rel="prefetch" href="/assets/js/94.315f4e94.js"><link rel="prefetch" href="/assets/js/95.ccd6c6bf.js"><link rel="prefetch" href="/assets/js/96.0c6d89d0.js"><link rel="prefetch" href="/assets/js/97.1a9f10a9.js"><link rel="prefetch" href="/assets/js/98.43be3caa.js"><link rel="prefetch" href="/assets/js/99.54c8207b.js">
    <link rel="stylesheet" href="/assets/css/0.styles.0dbae9ec.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/" class="home-link router-link-active"><!----> <span class="site-name">whoway</span></a> <div class="links" style="max-width:nullpx;"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">🎓Coding</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/00.Coding/TheBeautyOfProgramming/" class="nav-link">🔖编程之美题解</a></li><li class="dropdown-item"><!----> <a href="/00.Coding/CodeWarehouse/" class="nav-link">🔖代码意识流</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">🚀语言</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/01.Language/Overview/" class="nav-link">🔖概述</a></li><li class="dropdown-item"><!----> <a href="/01.Language/C/" class="nav-link">⭐️C</a></li><li class="dropdown-item"><!----> <a href="/01.Language/Cpp/" class="nav-link router-link-active">🚀C++</a></li><li class="dropdown-item"><!----> <a href="/01.Language/Java/" class="nav-link">☕️Java</a></li><li class="dropdown-item"><!----> <a href="/01.Language/Python/" class="nav-link">🧩Python3</a></li></ul></div></div><div class="nav-item"><a href="/02.Hardware/" class="nav-link">✔️硬件基础</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">⭐️软件基础</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/03.Software/01.DataStructureAndAlgorithm/" class="nav-link">🐾数据结构和算法</a></li><li class="dropdown-item"><!----> <a href="/03.Software/02.OS/" class="nav-link">💻操作系统</a></li><li class="dropdown-item"><!----> <a href="/03.Software/03.Net/" class="nav-link">☁️计算机网络</a></li><li class="dropdown-item"><!----> <a href="/03.Software/04.SE/" class="nav-link">✅软件工程</a></li></ul></div></div><div class="nav-item"><a href="/04.Database/" class="nav-link">🎨数据库</a></div><div class="nav-item"><a href="/05.Engineer/" class="nav-link">🔖学术/工程</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">⚙️工具</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/06.Tools/01.employment/" class="nav-link">🔖求职</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/02.efficiency/" class="nav-link">🚀效能</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/03.windows/" class="nav-link">⚙️Windows</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/04.design/" class="nav-link">🧩设计</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/05.linux/" class="nav-link">🐉Linux</a></li></ul></div></div><div class="nav-item"><a href="https://github.com/whoway" target="_blank" rel="noopener noreferrer" class="nav-link external">
  GitHub
  <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div> <!----></nav></div></header> <div class="sidebar-mask"></div> <div class="sidebar"><nav class="nav-links"><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">🎓Coding</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/00.Coding/TheBeautyOfProgramming/" class="nav-link">🔖编程之美题解</a></li><li class="dropdown-item"><!----> <a href="/00.Coding/CodeWarehouse/" class="nav-link">🔖代码意识流</a></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">🚀语言</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/01.Language/Overview/" class="nav-link">🔖概述</a></li><li class="dropdown-item"><!----> <a href="/01.Language/C/" class="nav-link">⭐️C</a></li><li class="dropdown-item"><!----> <a href="/01.Language/Cpp/" class="nav-link router-link-active">🚀C++</a></li><li class="dropdown-item"><!----> <a href="/01.Language/Java/" class="nav-link">☕️Java</a></li><li class="dropdown-item"><!----> <a href="/01.Language/Python/" class="nav-link">🧩Python3</a></li></ul></div></div><div class="nav-item"><a href="/02.Hardware/" class="nav-link">✔️硬件基础</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">⭐️软件基础</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/03.Software/01.DataStructureAndAlgorithm/" class="nav-link">🐾数据结构和算法</a></li><li class="dropdown-item"><!----> <a href="/03.Software/02.OS/" class="nav-link">💻操作系统</a></li><li class="dropdown-item"><!----> <a href="/03.Software/03.Net/" class="nav-link">☁️计算机网络</a></li><li class="dropdown-item"><!----> <a href="/03.Software/04.SE/" class="nav-link">✅软件工程</a></li></ul></div></div><div class="nav-item"><a href="/04.Database/" class="nav-link">🎨数据库</a></div><div class="nav-item"><a href="/05.Engineer/" class="nav-link">🔖学术/工程</a></div><div class="nav-item"><div class="dropdown-wrapper"><a class="dropdown-title"><span class="title">⚙️工具</span> <span class="arrow right"></span></a> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/06.Tools/01.employment/" class="nav-link">🔖求职</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/02.efficiency/" class="nav-link">🚀效能</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/03.windows/" class="nav-link">⚙️Windows</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/04.design/" class="nav-link">🧩设计</a></li><li class="dropdown-item"><!----> <a href="/06.Tools/05.linux/" class="nav-link">🐉Linux</a></li></ul></div></div><div class="nav-item"><a href="https://github.com/whoway" target="_blank" rel="noopener noreferrer" class="nav-link external">
  GitHub
  <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></div> <!----></nav>  <ul class="sidebar-links"><li><div class="sidebar-group first"><p class="sidebar-heading open"><span>C++98核心详解</span> <!----></p> <ul class="sidebar-group-items"><li><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#📑-目录" class="sidebar-link">📑 目录</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#✅难点" class="sidebar-link">✅难点</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#✅c-和c定位纠偏" class="sidebar-link">✅C++和C定位纠偏</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#✅『oob』基于对象的程序设计" class="sidebar-link">✅『OOB』基于对象的程序设计</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#_01-3加1对比" class="sidebar-link">01.3加1对比</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#_1-1-class" class="sidebar-link">1.1.class</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#_1-2-struct『c-中』" class="sidebar-link">1.2.struct『C++中』</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#_1-3-union『c-中』" class="sidebar-link">1.3.union『C++中』</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#_1-4-enum『只有它不是特殊的类』" class="sidebar-link">1.4.enum『只有它不是特殊的类』</a></li></ul></li><li><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#_02-类的『成员变量』和『非成员变量』⭐️" class="sidebar-link">02.类的『成员变量』和『非成员变量』⭐️</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#_2-1-成员变量" class="sidebar-link">2.1.成员变量</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#_2-2-非成员变量" class="sidebar-link">2.2.非成员变量</a></li></ul></li><li><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#_03-类的『成员函数』和『非成员函数』⭐️" class="sidebar-link">03.类的『成员函数』和『非成员函数』⭐️</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#_3-1-成员函数" class="sidebar-link">3.1.成员函数</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#_3-2-非成员函数" class="sidebar-link">3.2.非成员函数</a></li></ul></li><li><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#_04-big-three讲解" class="sidebar-link">04.Big Three讲解</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#_4-1-构造函数详解" class="sidebar-link">4.1.构造函数详解</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#_4-2-析构函数详解" class="sidebar-link">4.2.析构函数详解</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#_4-2-2-是否私有" class="sidebar-link">4.2.2.是否私有</a></li></ul></li><li><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#_05-访问属性" class="sidebar-link">05.访问属性</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#_5-1-内部访问和对象访问" class="sidebar-link">5.1.内部访问和对象访问</a></li></ul></li><li><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#_06-namespace命名空间" class="sidebar-link">06.namespace命名空间</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#✅『oop』面向对象的程序设计" class="sidebar-link">✅『OOP』面向对象的程序设计</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#_1-1-类型转换函数" class="sidebar-link">1.1.类型转换函数</a></li></ul></li><li><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#_01-辨析overload、override、overwrite⭐️" class="sidebar-link">01.辨析Overload、Override、Overwrite⭐️</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#✅区分overload、overwrite和override" class="sidebar-link">✅区分Overload、Overwrite和Override</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#成员函数加和不加virtual算不算重载？" class="sidebar-link">成员函数加和不加virtual算不算重载？</a></li></ul></li><li><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#_02-多态与虚函数" class="sidebar-link">02.多态与虚函数</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#_2-1-static变量的说明" class="sidebar-link">2.1.static变量的说明</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#_2-2-虚函数相关" class="sidebar-link">2.2.虚函数相关</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#_2-2-虚函数能不能inline" class="sidebar-link">2.2.虚函数能不能inline</a></li></ul></li><li><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#_03-『多态神器』-多态3条件" class="sidebar-link">03.『多态神器』-多态3条件</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#_3-1-条件1和条件2❎『非多态』" class="sidebar-link">3.1.条件1和条件2❎『非多态』</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#_3-2-条件3❎『非多态』" class="sidebar-link">3.2.条件3❎『非多态』</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#_3-3-虚析构函数" class="sidebar-link">3.3.虚析构函数</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#_3-4-『添加作用域的调用』" class="sidebar-link">3.4.『添加作用域的调用』</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#_3-5-静态绑定的核心理解『易错难点』⭐️" class="sidebar-link">3.5.静态绑定的核心理解『易错难点』⭐️</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#_3-6-const对象" class="sidebar-link">3.6.const对象</a></li></ul></li><li><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#_04-构造函数（ctor）和析构函数（dtor）相关⭐️" class="sidebar-link">04.构造函数（ctor）和析构函数（dtor）相关⭐️</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#_4-1-c-构造函数和析构函数可以是虚函数嘛？" class="sidebar-link">4.1.C++ 构造函数和析构函数可以是虚函数嘛？</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#_4-2-构造函数中调用虚函数会怎么样？" class="sidebar-link">4.2.构造函数中调用虚函数会怎么样？</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#_4-3-析构函数中调用虚函数会怎么样？" class="sidebar-link">4.3.析构函数中调用虚函数会怎么样？</a></li></ul></li><li><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#⭐️04-『运算符重载』详解" class="sidebar-link">⭐️04.『运算符重载』详解</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#_4-1-重载的2种函数类型" class="sidebar-link">4.1.重载的2种函数类型</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#_4-2-可以重载，但建议不要重载的运算符" class="sidebar-link">4.2.可以重载，但建议不要重载的运算符</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#_4-3-不能重载的5个运算符记忆" class="sidebar-link">4.3.不能重载的5个运算符记忆</a></li></ul></li><li><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#⭐️05-c-中『栈』和『堆』" class="sidebar-link">⭐️05.C++中『栈』和『堆』</a><ul class="sidebar-sub-headers"></ul></li><li><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#✅杂谈" class="sidebar-link">✅杂谈</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#_01-常量表达式" class="sidebar-link">01.常量表达式</a></li><li class="sidebar-sub-header"><a href="/01.Language/Cpp/01.C%2B%2B98%E6%A0%B8%E5%BF%83%E8%AF%A6%E8%A7%A3.html#_02-c-98关键字" class="sidebar-link">02.C++98关键字</a></li></ul></li></ul></div></li></ul> </div> <div class="page"> <div class="content"><h1 id="c-98核心详解"><a href="#c-98核心详解" class="header-anchor">#</a> C++98核心详解</h1> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>&lt;font style=&quot;background:pink&quot;&gt;
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><h2 id="📑-目录"><a href="#📑-目录" class="header-anchor">#</a> 📑 目录</h2> <p>[TOC]</p> <blockquote><p>学C++的利器：</p></blockquote> <ul><li>this指针</li> <li>虚函数表</li> <li>内存管理</li> <li>《STL源码剖析》</li></ul> <h2 id="✅难点"><a href="#✅难点" class="header-anchor">#</a> ✅难点</h2> <ul><li>因为<strong>对于非虚成员函数，Ｃ++这门语言是静态绑定的</strong>。</li> <li><font style="background:yellow;">这也是Ｃ++语言和其它语言Java, Python的一个显著区别</font></li></ul> <h2 id="✅c-和c定位纠偏"><a href="#✅c-和c定位纠偏" class="header-anchor">#</a> ✅C++和C定位纠偏</h2> <ul><li>C和C++从来就不是一个东西！</li></ul> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>C++部分兼容C
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><ul><li>参考<a href="https://www.nowcoder.com/profile/2876549" target="_blank" rel="noopener noreferrer">牛油的回答<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li></ul> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code>如 <span class="token keyword">int</span> <span class="token operator">*</span>a<span class="token punctuation">;</span> a <span class="token operator">=</span> <span class="token function">malloc</span><span class="token punctuation">(</span><span class="token number">16</span><span class="token punctuation">)</span><span class="token punctuation">;</span> 在C<span class="token operator">++</span>中要强制转换才行
个人测试C99中有些特性在C<span class="token operator">++</span>中也没有
如下面的代码： 定义一个二维变长数组作参数的函数。
    gcc、clang可以编译运行通过。g<span class="token operator">++</span>、clang<span class="token operator">++</span>编译不通过。
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br></div></div><div class="language-c line-numbers-mode"><pre class="language-c"><code>C<span class="token operator">++</span><span class="token number">11</span>中没有的C99<span class="token operator">/</span>C11特性
    虽然在过去C或多或少可以看作是C<span class="token operator">++</span>的子集，但是C99标准增加了一些C<span class="token operator">++</span>没有的新特性
下面列出了一些只有C99<span class="token operator">/</span>C11中才有的特性<span class="token operator">:</span>	
	指定初始化器<span class="token punctuation">;</span>
	复合初始化器<span class="token punctuation">(</span>Compound initializer<span class="token punctuation">)</span><span class="token punctuation">;</span>
	受限指针<span class="token punctuation">(</span> Restricted pointer<span class="token punctuation">)</span><span class="token punctuation">(</span>即，restric指针<span class="token punctuation">)</span><span class="token punctuation">;</span>变长数组<span class="token punctuation">;</span>
	伸缩型数组成员<span class="token punctuation">;</span>
	带可变数量参数的宏。

注意
以上所列只是在特定时期内的情况，随着时间的推移和C、C<span class="token operator">++</span>的不断发展，列表中的项会有所增减。
    例如，C<span class="token operator">++</span><span class="token number">14</span>新增的一个特性就与『C99的变长数组』类似。
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br></div></div><ul><li>参考自：《C Primer Plus》P730</li></ul> <h2 id="✅『oob』基于对象的程序设计"><a href="#✅『oob』基于对象的程序设计" class="header-anchor">#</a> ✅『OOB』基于对象的程序设计</h2> <h2 id="_01-3加1对比"><a href="#_01-3加1对比" class="header-anchor">#</a> 01.3加1对比</h2> <ul><li>class</li> <li>struct</li> <li>union</li> <li>enum『枚举类型<strong>是1种基本类型</strong>，不是1种构造类型，因为它不能再分解为任何其他基本类型，比如，<code>class</code>，<code>struct</code>，<code>union</code>』</li></ul> <h3 id="_1-1-class"><a href="#_1-1-class" class="header-anchor">#</a> 1.1.<code>class</code></h3> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token number">1</span>、继承，默认是『<span class="token keyword">private</span>继承』
<span class="token number">2</span>、内部可以放成员变量，成员函数，默认成员变量访问控制是：『<span class="token keyword">private</span>』
<span class="token number">3</span>、成员函数类：
    有』构造函数
    有』析构函数
    有』虚函数
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><h3 id="_1-2-struct『c-中』"><a href="#_1-2-struct『c-中』" class="header-anchor">#</a> 1.2.<code>struct</code>『C++中』</h3> <blockquote><p>本质：<strong>是一种class</strong></p></blockquote> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token number">1</span>、继承，默认是『<span class="token keyword">public</span>继承』____
<span class="token number">2</span>、内部可以放成员变量，成员函数，默认成员变量访问控制是：『<span class="token keyword">public</span>』__
<span class="token number">3</span>、成员函数类：
    有』构造函数
    有』析构函数
    有』虚函数
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span><span class="token string">&lt;bits/stdc++.h&gt;</span></span>
<span class="token keyword">using</span> <span class="token keyword">namespace</span> std<span class="token punctuation">;</span>

<span class="token keyword">struct</span> <span class="token class-name">A</span>
<span class="token punctuation">{</span>
	<span class="token keyword">private</span><span class="token operator">:</span>
		<span class="token keyword">int</span> a<span class="token punctuation">;</span>
	<span class="token keyword">public</span><span class="token operator">:</span>
		<span class="token function">A</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span><span class="token function">a</span><span class="token punctuation">(</span><span class="token operator">-</span><span class="token number">99</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>

		<span class="token keyword">void</span> <span class="token function">demo</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
		<span class="token punctuation">{</span>
			cout<span class="token operator">&lt;&lt;</span><span class="token string">&quot;a=&quot;</span><span class="token operator">&lt;&lt;</span><span class="token keyword">this</span><span class="token operator">-&gt;</span>a<span class="token operator">&lt;&lt;</span>endl<span class="token punctuation">;</span>
		<span class="token punctuation">}</span>

		<span class="token operator">~</span><span class="token function">A</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
		<span class="token punctuation">{</span>
			cout<span class="token operator">&lt;&lt;</span><span class="token string">&quot;die AAA&quot;</span><span class="token operator">&lt;&lt;</span>endl<span class="token punctuation">;</span>
		<span class="token punctuation">}</span>
		
		<span class="token keyword">virtual</span> <span class="token keyword">void</span> <span class="token function">myPoly</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
		<span class="token punctuation">{</span>
			cout<span class="token operator">&lt;&lt;</span><span class="token string">&quot;*AAA******&quot;</span><span class="token operator">&lt;&lt;</span>endl<span class="token punctuation">;</span>
		<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>


<span class="token comment">//struct B : private A</span>
<span class="token comment">//下面的写法，等价于，struct B : public A</span>
<span class="token keyword">struct</span> <span class="token class-name">B</span> <span class="token operator">:</span>  <span class="token base-clause"><span class="token class-name">A</span></span>
<span class="token punctuation">{</span>
	<span class="token keyword">int</span> b<span class="token punctuation">;</span>
	<span class="token function">B</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span><span class="token function">b</span><span class="token punctuation">(</span><span class="token operator">-</span><span class="token number">888</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>

	<span class="token keyword">void</span> <span class="token function">demo</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	<span class="token punctuation">{</span>
		cout<span class="token operator">&lt;&lt;</span><span class="token string">&quot;b=&quot;</span><span class="token operator">&lt;&lt;</span>b<span class="token operator">&lt;&lt;</span>endl<span class="token punctuation">;</span>
	<span class="token punctuation">}</span>

	<span class="token operator">~</span><span class="token function">B</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	<span class="token punctuation">{</span>
		cout<span class="token operator">&lt;&lt;</span><span class="token string">&quot;die BBB&quot;</span><span class="token operator">&lt;&lt;</span>endl<span class="token punctuation">;</span>
	<span class="token punctuation">}</span>

	<span class="token keyword">virtual</span> <span class="token keyword">void</span> <span class="token function">myPoly</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
	<span class="token punctuation">{</span>
		cout<span class="token operator">&lt;&lt;</span><span class="token string">&quot;*BBBB******&quot;</span><span class="token operator">&lt;&lt;</span>endl<span class="token punctuation">;</span>
	<span class="token punctuation">}</span>
	
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>

	<span class="token comment">//因为加上了system(&quot;pause&quot;);所以需要下面这样挂掉B，才能知道B的析构函数被调用</span>

	<span class="token punctuation">{</span>
		A one<span class="token punctuation">;</span>
		one<span class="token punctuation">.</span><span class="token function">demo</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

		B two<span class="token punctuation">;</span>
		two<span class="token punctuation">.</span><span class="token function">demo</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> 

		A <span class="token operator">*</span> pointer<span class="token operator">=</span><span class="token keyword">new</span> B<span class="token punctuation">;</span>
		pointer<span class="token operator">-&gt;</span><span class="token function">myPoly</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token punctuation">}</span>

	<span class="token function">system</span><span class="token punctuation">(</span><span class="token string">&quot;pause&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br><span class="line-number">40</span><br><span class="line-number">41</span><br><span class="line-number">42</span><br><span class="line-number">43</span><br><span class="line-number">44</span><br><span class="line-number">45</span><br><span class="line-number">46</span><br><span class="line-number">47</span><br><span class="line-number">48</span><br><span class="line-number">49</span><br><span class="line-number">50</span><br><span class="line-number">51</span><br><span class="line-number">52</span><br><span class="line-number">53</span><br><span class="line-number">54</span><br><span class="line-number">55</span><br><span class="line-number">56</span><br><span class="line-number">57</span><br><span class="line-number">58</span><br><span class="line-number">59</span><br><span class="line-number">60</span><br><span class="line-number">61</span><br><span class="line-number">62</span><br><span class="line-number">63</span><br><span class="line-number">64</span><br><span class="line-number">65</span><br><span class="line-number">66</span><br><span class="line-number">67</span><br><span class="line-number">68</span><br><span class="line-number">69</span><br><span class="line-number">70</span><br></div></div><h3 id="_1-3-union『c-中』"><a href="#_1-3-union『c-中』" class="header-anchor">#</a> 1.3.<code>union</code>『C++中』</h3> <blockquote><p>本质：它是一种<strong>特殊的类</strong></p></blockquote> <ul><li>参考《后台开发》</li></ul> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token number">1</span>、继承：继承自别人<span class="token operator">/</span>能给别人继承都『不可以』______
<span class="token number">2</span>、内部可以放成员变量，成员函数，默认成员变量访问控制是：『<span class="token keyword">public</span>』__
<span class="token number">3</span>、成员函数类：
    有』构造函数
    有』析构函数
    不可以有』虚函数______
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><h3 id="_1-4-enum『只有它不是特殊的类』"><a href="#_1-4-enum『只有它不是特殊的类』" class="header-anchor">#</a> 1.4.<code>enum</code>『只有它不是特殊的类』</h3> <blockquote><p>枚举类型<strong>是1种基本类型</strong>，不是1种构造类型，因为它不能再分解为任何其他基本类型『比如，<code>class</code>，<code>struct</code>，<code>union</code>』</p></blockquote> <h2 id="_02-类的『成员变量』和『非成员变量』⭐️"><a href="#_02-类的『成员变量』和『非成员变量』⭐️" class="header-anchor">#</a> 02.类的『成员变量』和『非成员变量』⭐️</h2> <img src="/assets/img/成员变量和非成员变量.abeeccdf.png"> <h3 id="_2-1-成员变量"><a href="#_2-1-成员变量" class="header-anchor">#</a> 2.1.成员变量</h3> <p><strong>书中记载</strong>：</p> <ul><li>nonstatic member 非静态成员
<ul><li>普通数据成员</li> <li>const数据成员</li></ul></li> <li>static member 静态成员</li></ul> <p><strong>static成员变量</strong></p> <ul><li>c++的一个类中『<strong>声明</strong>』一个static成员变量，static是加了访问控制的全局变量，不被继承</li> <li>类和子类对象，static变量占有一份内存</li></ul> <blockquote><p>重点理解：<strong>静态成员变量的初始化一定要在『类外』</strong></p></blockquote> <p>原因： 因为静态成员变量本身在main函数未开始时已经存在。不要让成员变量的初始化依赖于对象。不用对象，难到就不能用这一变量了吗？如果将初始化放在类内。那么<strong>当不声明对象时</strong>，无法使用这一静态变量。编译器报错为‘undeclared identifier’</p> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>类中的声明和定义辨析：（重点、难点）
笔者的看法是：
1、逻辑上说明是一起，只能表示可以『声明』在一起。（声明的门槛很低）
2、具体内存在哪分配，这个决定『能不能在类内』进行『定义』

比如：
1、友元函数在『类内』声明，不能在『类内』定义，能在『类外』定义
2、static成员变量在『类内』声明，不能在『类内』定义，能在『类外』定义
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><blockquote><p>参考自：<a href="https://www.huaweicloud.com/articles/4637f3d11eb3fd9a38e017041e23e50a.html" target="_blank" rel="noopener noreferrer">华为云<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></p></blockquote> <p><strong>static和非static特点</strong></p> <ul><li>静态成员存在于<strong>内存</strong>，非静态成员需要实例化才会分配内存（注意，也就是在虚拟内存空间中，表示的是.bss和.data段中）</li> <li>非静态成员的生存期决定于该类的生存期，而静态成员生存期则与程序生命期相同</li></ul> <h3 id="_2-2-非成员变量"><a href="#_2-2-非成员变量" class="header-anchor">#</a> 2.2.非成员变量</h3> <h2 id="_03-类的『成员函数』和『非成员函数』⭐️"><a href="#_03-类的『成员函数』和『非成员函数』⭐️" class="header-anchor">#</a> 03.类的『成员函数』和『非成员函数』⭐️</h2> <img src="/assets/img/成员函数和非成员函数.18eaed6b.png"> <blockquote><p>我的<a href="http://naotu.baidu.com/file/02d2413a51829d0c29226a23718613ad?token=d83f2eb1c2d887a6" target="_blank" rel="noopener noreferrer">百度脑图<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></p> <p>说明：成员函数的分类，需要考虑排序组合，<strong>是很多，很复杂</strong>的，不然就只能一个一个维度去分类。</p></blockquote> <h3 id="_3-1-成员函数"><a href="#_3-1-成员函数" class="header-anchor">#</a> 3.1.成员函数</h3> <ul><li>到底什么是成员函数？</li> <li>类的成员函数：是定义为<strong>类的一部分</strong>的函数，有时也被称为方法。（C++primer第5版，P20）</li> <li>各类函数中：构造函数、析构函数、拷贝初始化构造函数等是类的成员函数。</li> <li>成员函数分下面3类（应该说是2类，纯虚函数属于虚函数的子集的话）</li></ul> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>1、非虚函数（non-virtual 函数）：
你『不希望』派生类（derived class）重新定义 (override, 复写) 它.



2、虚函数（virtual 函數）：
你希望 derived class 重新定义 (override, 复写) 它，且你对它已有『默认』定义。
3、纯虚函数（pure virtual 函數）：
你希望 derived class 『一定』要重新定义 (override 复写)
它，你对它沒有默认定义。

PS：我们把不是纯的虚函数的虚函数叫作（impure virtual函数）
PS：在语法上，我们只要在任何一个函数前面加上virtual这样一个关键字，它就成为一个虚函数。
数据可以被继承下来，就是占它用了内存。
函数的继承如何理解？但是不应该从内存角度理解，函数的继承，继承的是调用权利

PS：其实纯虚函数是可以有定义的！！
&gt; 出处：《C++Primer》中文版第五版541页第22行。
我们可以为纯虚函数提供定义，不过函数体『必须定义在类的外部』。若定义在类的内部，会出现错误：pure-specifier on function-definition。
》 虚函数是可以定义『在类的内部的』，外部也可以！
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br></div></div><blockquote><p>参考自：侯捷</p></blockquote> <ul><li><p><strong>override</strong>这个术语，在这个主题不能随便用！！</p></li> <li><p>这个术语，<strong>一定是用在『虚函数』被重新定义，才能够叫（override）</strong></p></li> <li><p>🐾<font style="background:yellow;">无法继承的『static成员函数』</font></p></li> <li><p><strong>纯虚函数</strong>：只提供一个<strong>接口</strong>，具体实现方法需要<strong>派生类</strong>自己去实现，纯虚函数本身不可以有实现</p></li> <li><p><strong>非虚函数</strong>：提供接口，并且强制<strong>实现</strong>方法</p></li></ul> <blockquote><p>根据《<strong>深度探索C++对象模型</strong>》一书所说：</p></blockquote> <p>原始的“C with Classes”只支持，<strong>（Nonstatic member function）非静态成员函数</strong></p> <p><strong>（Virtual function）虚函数</strong>，是在20世纪80年代中期加入进来的。</p> <p><strong>（Static member function）静态成员函数</strong>是最后被引入的一种函数类型!</p> <p>书中说道：<font style="background:blue;">C++支持3种类型的**（member function）成员函数**</font>『记住下面的』</p> <ul><li>1、static member function</li> <li>2、nonstatic member function
<ul><li>1、普通的成员函数</li> <li>2、const成员函数</li></ul></li> <li>3、virtual member function</li></ul> <p>成员函数中<strong>易错</strong>：</p> <ul><li>由于成员函数中的const成员函数，const<strong>实际</strong>上修饰的是<strong>this指针</strong>。</li> <li><font style="background:yellow;">所以<strong>在成员函数</strong>中，<strong>static</strong>和<strong>const不能同时</strong>修饰同一个成员函数</font>，因为static成员函数没有this指针。</li></ul> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span><span class="token string">&lt;bits/stdc++.h&gt;</span></span>
<span class="token keyword">using</span> <span class="token keyword">namespace</span> std<span class="token punctuation">;</span>

<span class="token comment">//这行没错</span>
<span class="token keyword">static</span> <span class="token keyword">const</span> <span class="token keyword">int</span> maxn<span class="token operator">=</span><span class="token number">1000</span><span class="token operator">+</span><span class="token number">5</span><span class="token punctuation">;</span>

<span class="token keyword">class</span> <span class="token class-name">A</span>
<span class="token punctuation">{</span>
	<span class="token keyword">public</span><span class="token operator">:</span>
    	<span class="token comment">//修饰变量，这行却没错</span>
		<span class="token keyword">static</span> <span class="token keyword">const</span> <span class="token keyword">int</span> a<span class="token operator">=</span><span class="token number">9</span><span class="token punctuation">;</span>
  
    	<span class="token comment">//下面会出错，[Error] static member function 'static void A::demo()' cannot have cv-qualifier</span>
		<span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">demo</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token keyword">const</span> 
		<span class="token punctuation">{</span>
			cout<span class="token operator">&lt;&lt;</span>a<span class="token operator">&lt;&lt;</span>endl<span class="token punctuation">;</span>
		<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
	<span class="token class-name">A</span><span class="token operator">::</span><span class="token function">demo</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br></div></div><h3 id="_3-2-非成员函数"><a href="#_3-2-非成员函数" class="header-anchor">#</a> 3.2.非成员函数</h3> <h4 id="_3-2-1-友元函数"><a href="#_3-2-1-友元函数" class="header-anchor">#</a> 3.2.1.友元函数</h4> <ul><li>注意：<font style="background:yellow;">友元函数不是类的成员函数！</font>（<strong>欢聚时代</strong>）</li></ul> <p>1、友元函数的『<strong>声明</strong>』可以放在类<strong>声明</strong>的任何地方，不受访问限定关键字private、protected、public的限制</p> <p>2、尽管友元函数的<strong>原型</strong>有在<strong>类的定义</strong>中出现过，但是<strong>友元函数并不是成员函数</strong>。</p> <p>3、友元是一种<strong>定义在类外部</strong>的普通函数（友元函数既可以在类的内部，也可以在类的外部定义《<strong>C++primer</strong>》中说了），但它需要在类体内进行<strong>说明『声明』</strong>，为了与该类的成员函数加以区别，在说明时前面加以关键字friend</p> <blockquote><p>参考自：菜鸟教程<a href="https://www.runoob.com/cplusplus/cpp-friend-functions.html" target="_blank" rel="noopener noreferrer">C++ 友元函数<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></p></blockquote> <h4 id="_3-2-2-友元"><a href="#_3-2-2-友元" class="header-anchor">#</a> 3.2.2.友元</h4> <p>『『<font style="background:yellow;">友元函数是不能被继承的</font>——解释，你父亲的朋友不能继承给你？』』，<font style="background:yellow;">友元函数没有this指针</font>
友元只是破坏了类的隐藏性和封装性，<font style="background:yellow;">可以直接调用，不需要通过对象或者指针</font></p> <ul><li>一个基类的声明中有纯虚函数，该基类派生类一定不再是抽象类（错误）</li> <li>如果在派生类中没有对所有纯虚函数进行定义，则此派生类仍然是抽象类，不能用来定义对象。所以A错.</li> <li>构造函数不能被覆盖</li></ul> <h2 id="_04-big-three讲解"><a href="#_04-big-three讲解" class="header-anchor">#</a> 04.<code>Big Three</code>讲解</h2> <ul><li>参考自：侯捷的说法，好像来自《C++ Primer》</li></ul> <h3 id="_4-1-构造函数详解"><a href="#_4-1-构造函数详解" class="header-anchor">#</a> 4.1.构造函数详解</h3> <h4 id="_1-普通ctor（普通构造函数）"><a href="#_1-普通ctor（普通构造函数）" class="header-anchor">#</a> 1.普通ctor（普通构造函数）</h4> <ul><li>1、无参的普通构造函数</li> <li>2、有参的普通构造函数
<ul><li>（1）类型转换构造函数：只有1个参数的普通构造函数一般都可以称作『类型转换构造函数』</li> <li>（2）其他有参的普通构造函数</li></ul></li></ul> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token keyword">class</span> <span class="token class-name">A</span>
<span class="token punctuation">{</span>
    <span class="token keyword">public</span><span class="token operator">:</span>
    	<span class="token comment">//无参的『普通构造函数』</span>
    	<span class="token function">A</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
    	<span class="token comment">//有参的『普通构造函数』，并且由于只有1个参数，也叫『类型转换构造函数』</span>
    	<span class="token function">A</span><span class="token punctuation">(</span><span class="token keyword">int</span> i<span class="token punctuation">)</span>
        <span class="token punctuation">{</span>
          	cout<span class="token operator">&lt;&lt;</span><span class="token string">&quot;Int Constructor calles&quot;</span><span class="token operator">&lt;&lt;</span>endl<span class="token punctuation">;</span>  
        <span class="token punctuation">}</span><span class="token punctuation">;</span>
    	<span class="token function">A</span><span class="token punctuation">(</span>A <span class="token operator">&amp;</span> a<span class="token punctuation">)</span>
        <span class="token punctuation">{</span>
            cout<span class="token operator">&lt;&lt;</span><span class="token string">&quot;Copy ctor&quot;</span><span class="token operator">&lt;&lt;</span>endl<span class="token punctuation">;</span>
            <span class="token comment">//拷贝构造函数，原因是参数是『本类类型的引用』</span>
        <span class="token punctuation">}</span>
    
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br></div></div><h4 id="_2-copy-ctor"><a href="#_2-copy-ctor" class="header-anchor">#</a> 2.copy ctor</h4> <ul><li>又称；复制构造函数/拷贝构造函数/拷贝初始化构造函数</li></ul> <p>分为：</p> <ul><li>1、默认的『copy ctor』</li> <li>2、如果你自行编写了新的copy ctor，那么默认的copy ctor就不存在了</li></ul> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code>Demo <span class="token function">c2</span><span class="token punctuation">(</span>c1<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//会调用copy ctor，初始化</span>
Demo c2<span class="token operator">=</span>c1<span class="token punctuation">;</span><span class="token comment">//会调用copy ctor，注意是初始化，不是赋值！</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><h3 id="_4-2-析构函数详解"><a href="#_4-2-析构函数详解" class="header-anchor">#</a> 4.2.析构函数详解</h3> <h4 id="_4-2-1-有无virtual"><a href="#_4-2-1-有无virtual" class="header-anchor">#</a> 4.2.1.有无virtual</h4> <ul><li><strong>没有</strong>virtual的析构函数</li></ul> <blockquote><p>又称：<strong>一般</strong>的析构函数</p></blockquote> <ul><li><strong>有</strong>virtual的析构函数</li> <li>析构时区别 <code>delete</code> 和 <code>delete[]</code></li></ul> <h3 id="_4-2-2-是否私有"><a href="#_4-2-2-是否私有" class="header-anchor">#</a> 4.2.2.是否私有</h3> <ul><li>在C++中，为了让某个类<strong>只能通过new来创建</strong>（即如果直接创建对象，编译器将报错）</li> <li>应该将<strong>析构函数设为私有</strong></li></ul> <h2 id="_05-访问属性"><a href="#_05-访问属性" class="header-anchor">#</a> 05.访问属性</h2> <h3 id="_5-1-内部访问和对象访问"><a href="#_5-1-内部访问和对象访问" class="header-anchor">#</a> 5.1.内部访问和对象访问</h3> <ul><li>类的成员有三种访问属性，分别是public、protected、private，<a href="https://www.nowcoder.com/test/question/done?tid=44308742&qid=1618#summary" target="_blank" rel="noopener noreferrer">子类能够访问的成员<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>是</li></ul> <blockquote><p>参考牛客的答案：</p></blockquote> <img src="/assets/img/访问权限.ce788b0d.png"> <h2 id="_06-namespace命名空间"><a href="#_06-namespace命名空间" class="header-anchor">#</a> 06.<code>namespace</code>命名空间</h2> <ul><li>namespace，是指标识符的各种可见范围</li> <li>C++标准程序库中的所有标识符都被定义于一个名为std的namespace中。
<ul><li>一 ：<code>&lt;iostream&gt;</code>和&lt;iostream.h&gt;格式不一样，前者没有后缀，实际上，在你的编译器include文件夹里面可以看到，二者是两个文件，打开文件就会发现，里面的代码是不一样的。</li> <li>后缀为.h的头文件c++标准已经明确提出不支持了，早些的实现将标准库功能定义在<strong>全局空间</strong>里，声明在带.h后缀的头文件里，c++标准为了和C区别开，也为了正确使用命名空间，规定头文件不使用后缀.h。 因此。</li> <li>1、命名空间主要是将全局空间、『划分为更加小块的全局空间』</li></ul></li></ul> <h2 id="✅『oop』面向对象的程序设计"><a href="#✅『oop』面向对象的程序设计" class="header-anchor">#</a> ✅『OOP』面向对象的程序设计</h2> <ul><li>面向对象的三大基本特征：封装、继承、多态</li> <li>面向对象的五大基本原则：</li> <li>单一职责原则、开放封闭原则、里氏替换原则、依赖倒置原则、接口隔离原则</li></ul> <h3 id="_1-1-类型转换函数"><a href="#_1-1-类型转换函数" class="header-anchor">#</a> 1.1.类型转换函数</h3> <ul><li><p>带非默认参数的构造函数可以把基本类型数据转换成类类型对象。</p></li> <li><p>『类型转换函数』可以把类类型对象转换为其他指定类型对象。</p></li> <li><p>『类型转换函数』只能定义为一个类的成员函数，<strong>不能</strong>定义为类的<strong>友元函数。</strong></p></li></ul> <h2 id="_01-辨析overload、override、overwrite⭐️"><a href="#_01-辨析overload、override、overwrite⭐️" class="header-anchor">#</a> 01.辨析Overload、Override、Overwrite⭐️</h2> <ul><li><strong>重载(Overload)</strong>：
<ul><li><strong>在同一作用域内</strong>，函数名相同，函数的参数个数、参数类型或参数顺序三者中必须至少有一种不同。函数返回值的类型可以相同，也可以不相同。比如：发生在一个类内部。</li></ul></li></ul> <blockquote><p>郑莉：C++允许功能相近的函数在<strong>相同的作用域内</strong>以相同函数名声明。从而形成重载。方便使用记忆。</p> <p>《<strong>C++ Primer</strong>》P206，如果“<strong>同一作用域</strong>”内的几个函数名字相同但“形参列表”不同，我们称之为重载（<strong>overloaded</strong>）函数</p></blockquote> <ul><li><strong>重写(Override)</strong>：
<ul><li>也叫做<strong>覆盖</strong>，也叫<strong>复写</strong>，一般发生在子类和父类继承关系之间。子类<strong>重新定义</strong>父类中有相同名称和参数的<font style="background:yellow;">『<strong>虚函数</strong>』</font></li></ul></li> <li><strong>重定义</strong>：
<ul><li>也叫做<strong>隐藏</strong>，子类<strong>重新定义</strong>父类中有相同名称的<font style="background:yellow;">『<strong>非虚函数</strong>』 </font>( 参数列表可以不同 ) ，指派生类的函数屏蔽了与其同名的基类函数。可以理解成发生在继承中的重载。</li></ul></li></ul> <blockquote><p>参考：<a href="https://blog.csdn.net/u010275850/article/details/45583705" target="_blank" rel="noopener noreferrer">C++_重载、重写和重定义的区别<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></p></blockquote> <p>PS：但是，从很多英语教材上面，来说，重定义和重写都是单词（override），理解参考第4节</p> <ul><li>子类重新定义父类虚函数的方法叫做覆写</li> <li>多态是为了<strong>接口</strong>重用，封装和继承是为了代码重用</li></ul> <h3 id="✅区分overload、overwrite和override"><a href="#✅区分overload、overwrite和override" class="header-anchor">#</a> ✅区分Overload、Overwrite和Override</h3> <ul><li>注意，由于这3个词的翻译很尴尬，众说纷纭，我们直接考虑单词来</li> <li>『记忆版』</li></ul> <blockquote><p>参考：<a href="https://blog.csdn.net/jszhangyili/article/details/7570311" target="_blank" rel="noopener noreferrer">CSDN的jszhangyili博客<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></p></blockquote> <img src="/assets/img/class中函数3大概念.43294c4e.png"> <blockquote><p>都是在函数名相同的时候，都不考虑返回值的情况下，我们讨论下面3组</p></blockquote> <ul><li>Overload
<ul><li><strong>相同作用域</strong>『可以不是class中』
<ul><li>参数相同，如果在class中，这样写就很奇怪了，<font style="background:yellow;">报错</font></li> <li>参数不同，就是重载</li></ul></li></ul></li> <li>Override
<ul><li>继承体系，不同作用域</li> <li>基类该函数是虚函数</li> <li>参数相同</li></ul></li> <li>Overwrite
<ul><li>继承体系，不同作用域
<ul><li>情况1：参数不同，无论基类该函数是不是虚函数</li> <li>情况2：参数相同，基类如果是『非虚函数』，那么就意味着在派生类中重新定义一个函数，<font style="background:yellow;">也就是非多态</font></li></ul></li></ul></li></ul> <h3 id="成员函数加和不加virtual算不算重载？"><a href="#成员函数加和不加virtual算不算重载？" class="header-anchor">#</a> 成员函数加和不加virtual算不算重载？</h3> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span><span class="token string">&lt;bits/stdc++.h&gt;</span></span>
<span class="token keyword">using</span> <span class="token keyword">namespace</span> std<span class="token punctuation">;</span>

<span class="token keyword">class</span> <span class="token class-name">A</span>
<span class="token punctuation">{</span>
<span class="token keyword">public</span><span class="token operator">:</span>
    <span class="token function">A</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span><span class="token function">val</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span>
    <span class="token punctuation">{</span>

    <span class="token punctuation">}</span><span class="token punctuation">;</span>
    <span class="token keyword">void</span> <span class="token function">test</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;non-virtual=%d\n&quot;</span><span class="token punctuation">,</span>val<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">virtual</span> <span class="token keyword">void</span> <span class="token function">test</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;virtual=%d\n&quot;</span><span class="token punctuation">,</span> val<span class="token operator">+</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token keyword">private</span><span class="token operator">:</span>
    <span class="token keyword">int</span> val<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>


<span class="token keyword">class</span> <span class="token class-name">B</span> <span class="token operator">:</span> <span class="token base-clause"><span class="token keyword">public</span> <span class="token class-name">A</span></span>
<span class="token punctuation">{</span>
    <span class="token keyword">void</span> <span class="token function">test</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;BBB&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>


<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    A a<span class="token punctuation">;</span>
    a<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br></div></div><div class="language-bash line-numbers-mode"><pre class="language-bash"><code><span class="token punctuation">[</span>root@CentosLinux apue<span class="token punctuation">]</span><span class="token comment"># g++ demo.cpp </span>
demo.cpp:15:18: error: ‘virtual void A::test<span class="token punctuation">(</span><span class="token punctuation">)</span>’ cannot be overloaded
     virtual void test<span class="token punctuation">(</span><span class="token punctuation">)</span>
                  ^
demo.cpp:11:10: error: with ‘void A::test<span class="token punctuation">(</span><span class="token punctuation">)</span>’
     void test<span class="token punctuation">(</span><span class="token punctuation">)</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><ul><li>如上，<code>virtual void A::test()</code>不能被重载</li></ul> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span><span class="token string">&lt;bits/stdc++.h&gt;</span></span>
<span class="token keyword">using</span> <span class="token keyword">namespace</span> std<span class="token punctuation">;</span>

<span class="token keyword">int</span> num<span class="token operator">=</span><span class="token number">9</span><span class="token punctuation">;</span>
<span class="token keyword">void</span> <span class="token function">test</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;global=%d\n&quot;</span><span class="token punctuation">,</span> num<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">class</span> <span class="token class-name">A</span>
<span class="token punctuation">{</span>
<span class="token keyword">public</span><span class="token operator">:</span>
    <span class="token function">A</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span><span class="token function">val</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span>
    <span class="token punctuation">{</span>

    <span class="token punctuation">}</span><span class="token punctuation">;</span>

    <span class="token keyword">virtual</span> <span class="token keyword">void</span> <span class="token function">test</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        <span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;virtual=%d\n&quot;</span><span class="token punctuation">,</span> val<span class="token operator">+</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token keyword">private</span><span class="token operator">:</span>
    <span class="token keyword">int</span> val<span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    A a<span class="token punctuation">;</span>
    a<span class="token punctuation">.</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token function">test</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br></div></div><h2 id="_02-多态与虚函数"><a href="#_02-多态与虚函数" class="header-anchor">#</a> 02.多态与虚函数</h2> <h3 id="_2-1-static变量的说明"><a href="#_2-1-static变量的说明" class="header-anchor">#</a> 2.1.<code>static</code>变量的说明</h3> <p>c++的一个类中声明一个<strong>static成员变量</strong>，下面描述正确的是</p> <ul><li>static是加了访问控制的全局变量，『<strong>不被继承</strong>』，类和子类对象，static变量占有一份内存</li></ul> <h3 id="_2-2-虚函数相关"><a href="#_2-2-虚函数相关" class="header-anchor">#</a> 2.2.虚函数相关</h3> <ul><li>1、（static）静态函数不可以是虚函数『虚成员函数不可能是static 成员函数』</li> <li>2、（inline）虚函数可以声明为inline，但是编译器不会将其作为inline函数处理『有的选择题故意为难，但是其实虚函数是可以声明为inline的，但是分情况』』</li></ul> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token keyword">class</span> <span class="token class-name">a</span>
<span class="token punctuation">{</span>
    <span class="token keyword">inline</span> <span class="token keyword">virtual</span> <span class="token keyword">void</span> <span class="token function">test</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>
尽管以上写法是没有语法错误的，并且可以执行，但其实test函数已经不是内联函数了，因为<span class="token keyword">inline</span>只是对编译器的一个建议而已。
搞清本质就好。
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><h3 id="_2-2-虚函数能不能inline"><a href="#_2-2-虚函数能不能inline" class="header-anchor">#</a> 2.2.虚函数能不能inline</h3> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>Q:虚函数不能内联，但是语法不出错？

A:不是的，虚函数在『『没有表现多态的时候』』是可以内联的，表现多态的时候不能

『没有表现多态的时候』:内联只是对编译器的一种请求，是否真正内联要看编译器的处理，虚函数是可以内联的，但是编译器不会响应内联请求，即他会忽略内联说明，将其当做普通虚函数处理。

有说法说：
虚函数不可以内联，因为虚函数是在运行期的时候确定具体调用的函数，内联是在编译期的时候进行代码展开，两者冲突，所以没有一起使用的做法。『『这是不严谨的』』
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><h2 id="_03-『多态神器』-多态3条件"><a href="#_03-『多态神器』-多态3条件" class="header-anchor">#</a> 03.『多态神器』-多态3条件</h2> <ul><li>『『<code>动态绑定3条件</code>』』</li></ul> <blockquote><p>C++编译器，看到一个函数调用，他有2个考量，静态还是动态绑定：</p></blockquote> <ul><li>静态被编译成：<code>call</code></li> <li><font style="background:yellow;">动态绑定：符合某些条件就会做动态绑定，<strong>3个条件</strong></font></li></ul> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token number">1</span>、通过指针来调用『注意，引用显然也是的，因为底层也是指针』
<span class="token number">2</span>、这个指针是向上转型up cast了。『比如，派生类赋值给基类指针，基类指针调用』
<span class="token number">3</span>、调用虚函数
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><h3 id="_3-1-条件1和条件2❎『非多态』"><a href="#_3-1-条件1和条件2❎『非多态』" class="header-anchor">#</a> 3.1.条件1和条件2❎『非多态』</h3> <ul><li><p>例题1.</p></li> <li><p>牛客上配套习题：<a href="https://www.nowcoder.com/test/question/done?tid=44172669&qid=15197#summary" target="_blank" rel="noopener noreferrer">传送门<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></p></li> <li><p>题解：</p></li> <li><p>这一题中，最后一个c，是相当于强制类型转换，『或许叫：向下转型？？』，然后没有通过指针来调用</p></li> <li><p>用牛油的一个解释：动态绑定（多态）只有在指针和引用时才有效，其他情况下无效。</p></li></ul> <h3 id="_3-2-条件3❎『非多态』"><a href="#_3-2-条件3❎『非多态』" class="header-anchor">#</a> 3.2.条件3❎『非多态』</h3> <ul><li>例题2.</li></ul> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span><span class="token string">&lt;bits/stdc++.h&gt;</span></span>
<span class="token keyword">using</span> <span class="token keyword">namespace</span> std<span class="token punctuation">;</span>

<span class="token keyword">class</span> <span class="token class-name">A</span>
<span class="token punctuation">{</span>
	<span class="token keyword">public</span><span class="token operator">:</span>
		<span class="token keyword">void</span> <span class="token function">mytest</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
		<span class="token punctuation">{</span>
			cout<span class="token operator">&lt;&lt;</span><span class="token string">&quot;AAA&quot;</span><span class="token operator">&lt;&lt;</span>endl<span class="token punctuation">;</span>
		<span class="token punctuation">}</span>
		
<span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">class</span> <span class="token class-name">B</span><span class="token operator">:</span> <span class="token base-clause"><span class="token keyword">public</span> <span class="token class-name">A</span></span>
<span class="token punctuation">{</span>
	<span class="token keyword">public</span><span class="token operator">:</span>
		<span class="token keyword">virtual</span> <span class="token keyword">void</span> <span class="token function">mytest</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
		<span class="token punctuation">{</span>
			cout<span class="token operator">&lt;&lt;</span><span class="token string">&quot;BBB&quot;</span><span class="token operator">&lt;&lt;</span>endl<span class="token punctuation">;</span>
		<span class="token punctuation">}</span>	
<span class="token punctuation">}</span><span class="token punctuation">;</span> 

<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
	
	A <span class="token operator">*</span> p<span class="token operator">=</span> <span class="token keyword">new</span> B<span class="token punctuation">;</span>
	p<span class="token operator">-&gt;</span><span class="token function">mytest</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token comment">//输出的是AAA</span>
    
	
	<span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
 <span class="token punctuation">}</span> 

</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br></div></div><ul><li>本题不是动态绑定原因分析：</li> <li>1、通过指针来调用『注意，引用显然也是的，因为底层也是指针』
<ul><li>满足，用了<code>p-&gt;mytest();</code></li></ul></li> <li>2、这个指针是向上转型up cast了『比如，派生类赋值给基类指针，基类指针调用』
<ul><li>满足，A是B的基类</li></ul></li> <li>3、调用虚函数❎不满足
<ul><li>因为p指针是A类型的，但是在classA中该函数还不是『虚函数』，所以想走虚函数指针——虚函数表的路径走不通。</li></ul></li></ul> <h3 id="_3-3-虚析构函数"><a href="#_3-3-虚析构函数" class="header-anchor">#</a> 3.3.虚析构函数</h3> <ul><li><p>例题3</p></li> <li><p><font style="background:yellow;">虚析构函数：是为了解决基类的指针指向派生类对象，并且用『基类指针』删除派生类对象。</font></p></li></ul> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span> <span class="token string">&lt;iostream&gt;</span></span>
<span class="token keyword">using</span> <span class="token keyword">namespace</span> std<span class="token punctuation">;</span>
<span class="token keyword">class</span> <span class="token class-name">A</span>
<span class="token punctuation">{</span>
<span class="token keyword">public</span><span class="token operator">:</span>
    <span class="token function">A</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        cout <span class="token operator">&lt;&lt;</span> <span class="token string">&quot;1&quot;</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token function">A</span><span class="token punctuation">(</span>A <span class="token operator">&amp;</span>a<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        cout <span class="token operator">&lt;&lt;</span> <span class="token string">&quot;2&quot;</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token keyword">virtual</span> <span class="token operator">~</span><span class="token function">A</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        cout <span class="token operator">&lt;&lt;</span> <span class="token string">&quot;3&quot;</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token keyword">class</span> <span class="token class-name">B</span><span class="token operator">:</span> <span class="token base-clause"><span class="token keyword">public</span> <span class="token class-name">A</span></span>
<span class="token punctuation">{</span>
<span class="token keyword">public</span><span class="token operator">:</span>
    <span class="token function">B</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        cout <span class="token operator">&lt;&lt;</span> <span class="token string">&quot;4&quot;</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token function">B</span><span class="token punctuation">(</span>B <span class="token operator">&amp;</span>b<span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        cout <span class="token operator">&lt;&lt;</span> <span class="token string">&quot;5&quot;</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    <span class="token operator">~</span><span class="token function">B</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
    <span class="token punctuation">{</span>
        cout <span class="token operator">&lt;&lt;</span> <span class="token string">&quot;6&quot;</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
    A <span class="token operator">*</span>pa <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token function">B</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">delete</span> pa<span class="token punctuation">;</span>
    <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
<span class="token comment">//输出是：1 4 6 3</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br><span class="line-number">35</span><br><span class="line-number">36</span><br><span class="line-number">37</span><br><span class="line-number">38</span><br><span class="line-number">39</span><br><span class="line-number">40</span><br><span class="line-number">41</span><br><span class="line-number">42</span><br><span class="line-number">43</span><br></div></div><ul><li><p>考察的是对继承体系中的构造和析构函数调用顺序的理解。</p></li> <li><p>在调用new B()的时候，因为B继承A，所以会首先调用其父类的构造函数，输出1</p></li> <li><p>然后调用自己的构造函数，输出4</p></li> <li><p>//析构的时候，是会调用的</p></li> <li><p>对比，下面，如果去除掉A的析构函数的，虚函数</p></li></ul> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token operator">~</span><span class="token function">A</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><div class="language-txt line-numbers-mode"><pre class="language-text"><code>输出为：1 4 3
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br></div></div><ul><li>原因：
<ul><li><strong>静态绑定，this指针直接调用了A的析构</strong>，B的没有。</li> <li>很显然，有的时候，会出问题。</li></ul></li></ul> <h3 id="_3-4-『添加作用域的调用』"><a href="#_3-4-『添加作用域的调用』" class="header-anchor">#</a> 3.4.『添加作用域的调用』</h3> <ul><li><p>例题4</p></li> <li><p>多态情况下，不调用多态</p></li> <li><p>牛客网<a href="https://www.nowcoder.com/test/question/done?tid=44308742&qid=180817#summary" target="_blank" rel="noopener noreferrer">题目<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>：</p></li></ul> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>类B是类A的公有派生类，类A和类B中都定义了虚函数func(),p是一个指向类A对象的指针，则p-&gt;A::func()将（）？

正确答案: C   你的答案: C (正确)

A	调用类B中函数func()
B	即调用类A中函数，也调用类B中的函数
C	调用类A中函数func()
D	根据p所指的对象类型而确定调用类A中或类B中的函数func()
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br></div></div><ul><li>不论指针p是属于类A还是类B，也不论指针p指向的对象属于类A还是类B(当然，不能用类B的指针指向类A的对象)，<strong>因为加了作用域说明符<code>A::</code>，因此都只会调用类A的函数</strong>。</li></ul> <h3 id="_3-5-静态绑定的核心理解『易错难点』⭐️"><a href="#_3-5-静态绑定的核心理解『易错难点』⭐️" class="header-anchor">#</a> 3.5.静态绑定的核心理解『易错难点』⭐️</h3> <ul><li>例题5</li> <li>易错的题目<a href="https://www.nowcoder.com/test/question/done?tid=44470246&qid=44536#summary" target="_blank" rel="noopener noreferrer">传送门<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li></ul> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span><span class="token string">&lt;bits/stdc++.h&gt;</span></span>
<span class="token keyword">using</span> <span class="token keyword">namespace</span> std<span class="token punctuation">;</span>

<span class="token keyword">class</span> <span class="token class-name">A</span>
<span class="token punctuation">{</span>
	<span class="token keyword">public</span><span class="token operator">:</span>
		<span class="token keyword">void</span> <span class="token function">test</span><span class="token punctuation">(</span><span class="token punctuation">)</span> 
		<span class="token punctuation">{</span> 
			<span class="token function">printf</span><span class="token punctuation">(</span><span class="token string">&quot;test A&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span> 
		<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
	A <span class="token operator">*</span>pA <span class="token operator">=</span> <span class="token constant">NULL</span><span class="token punctuation">;</span><span class="token comment">//注意『这是个幌子』</span>
	pA<span class="token operator">-&gt;</span><span class="token function">test</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br></div></div><ul><li>有4个选项</li></ul> <div class="language-txt line-numbers-mode"><pre class="language-text"><code>问你选什么？
A    编译出错
B    程序运行奔溃
C    输出&quot;test A&quot;
D    输出乱码
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br></div></div><ul><li>答案：<strong>输出&quot;test A&quot;</strong></li> <li>原因：
<ul><li>因为<strong>对于非虚成员函数，Ｃ++这门语言是静态绑定的</strong>。</li> <li><font style="background:yellow;">这也是Ｃ++语言和其它语言Java, Python的一个显著区别</font></li> <li><code>//pA-&gt;test();</code>这语句的意图是：调用对象 pA 的 test 成员函数。如果这句话在Java或Python等动态绑定的语言之中，编译器生成的代码大概是：
<ul><li>找到 pA 的 test 成员函数，调用它。（注意，这里的找到是程序运行的时候才找的，这也是所谓动态绑定的含义：运行时才绑定这个函数名与其对应的实际代码。有些地方也称这种机制为迟绑定，晚绑定。）</li></ul></li> <li>但是对于C++。为了保证程序的运行时效率，Ｃ++的设计者认为凡是编译时能确定的事情，就不要拖到运行时再查找了。所以C++的编译器看到这句话会这么干：
<ul><li>１：查找 pA 的类型，发现它有一个非虚的成员函数叫 test 。（编译器干的）</li> <li>２：找到了，在这里生成一个函数调用，直接调<code>A:: test ( pA )</code>。</li></ul></li> <li>所以到了运行时，由于 test ()函数里面并没有任何需要解引用 pA 指针的代码，所以真实情况下也不会引发<code>segment fault</code>。
<ul><li><font style="background:yellow;">这里对成员函数的解析，和查找其对应的代码的工作都是在编译阶段完成而非运行时完成的，这就是所谓的静态绑定，也叫早绑定。正确理解C++的静态绑定可以理解一些特殊情况下C++的行为。『贼容易错』</font></li></ul></li></ul></li></ul> <h3 id="_3-6-const对象"><a href="#_3-6-const对象" class="header-anchor">#</a> 3.6.const对象</h3> <ul><li><p>例题6</p></li> <li><p>题目来源和<a href="https://www.nowcoder.com/test/question/done?tid=44470458&qid=1318#summary" target="_blank" rel="noopener noreferrer">参考资料<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></p></li></ul> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token macro property"><span class="token directive-hash">#</span><span class="token directive keyword">include</span><span class="token string">&lt;bits/stdc++.h&gt;</span></span>
<span class="token keyword">using</span> <span class="token keyword">namespace</span> std<span class="token punctuation">;</span>
<span class="token keyword">class</span> <span class="token class-name">A</span>
<span class="token punctuation">{</span>
<span class="token keyword">public</span><span class="token operator">:</span>
	<span class="token keyword">virtual</span> <span class="token keyword">void</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> cout <span class="token operator">&lt;&lt;</span> <span class="token string">&quot;A::f() &quot;</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
	<span class="token keyword">void</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">const</span> <span class="token punctuation">{</span> cout <span class="token operator">&lt;&lt;</span> <span class="token string">&quot;A::f() const &quot;</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token keyword">class</span> <span class="token class-name">B</span> <span class="token operator">:</span> <span class="token base-clause"><span class="token keyword">public</span> <span class="token class-name">A</span></span>
<span class="token punctuation">{</span>
<span class="token keyword">public</span><span class="token operator">:</span>
	<span class="token keyword">void</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> cout <span class="token operator">&lt;&lt;</span> <span class="token string">&quot;B::f() &quot;</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
	<span class="token keyword">void</span> <span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">const</span> <span class="token punctuation">{</span> cout <span class="token operator">&lt;&lt;</span> <span class="token string">&quot;B::f() const &quot;</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span>

<span class="token keyword">void</span> <span class="token function">g</span><span class="token punctuation">(</span><span class="token keyword">const</span> A <span class="token operator">*</span>a<span class="token punctuation">)</span>
<span class="token punctuation">{</span>
	a<span class="token operator">-&gt;</span><span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token keyword">int</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token punctuation">{</span>
	A <span class="token operator">*</span>p <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token function">B</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
	p<span class="token operator">-&gt;</span><span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>		<span class="token comment">//多态</span>
	<span class="token function">g</span><span class="token punctuation">(</span>p<span class="token punctuation">)</span><span class="token punctuation">;</span>		<span class="token comment">//先转换为const指针，由于只能调用const函数，所以不是多态了</span>
	<span class="token keyword">delete</span> <span class="token punctuation">(</span>p<span class="token punctuation">)</span><span class="token punctuation">;</span>
	<span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token comment">//输出</span>
<span class="token comment">//B::f() A::f() const</span>
<span class="token comment">//输出前面是因为多态</span>
<span class="token comment">//输出后面是因为不是多态！！！（注意）</span>
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br><span class="line-number">7</span><br><span class="line-number">8</span><br><span class="line-number">9</span><br><span class="line-number">10</span><br><span class="line-number">11</span><br><span class="line-number">12</span><br><span class="line-number">13</span><br><span class="line-number">14</span><br><span class="line-number">15</span><br><span class="line-number">16</span><br><span class="line-number">17</span><br><span class="line-number">18</span><br><span class="line-number">19</span><br><span class="line-number">20</span><br><span class="line-number">21</span><br><span class="line-number">22</span><br><span class="line-number">23</span><br><span class="line-number">24</span><br><span class="line-number">25</span><br><span class="line-number">26</span><br><span class="line-number">27</span><br><span class="line-number">28</span><br><span class="line-number">29</span><br><span class="line-number">30</span><br><span class="line-number">31</span><br><span class="line-number">32</span><br><span class="line-number">33</span><br><span class="line-number">34</span><br></div></div><ul><li>解释原因</li></ul> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code>由于<span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span>在基类中声明为虚的，则p<span class="token operator">-&gt;</span><span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span>根据『对象类型』<span class="token punctuation">(</span>B<span class="token punctuation">)</span>调用<span class="token class-name">B</span><span class="token operator">::</span><span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span>，此时编译器对虚方法使用动态联编，输出<span class="token class-name">B</span><span class="token operator">::</span><span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span>。
    
由于<span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">const</span>在基类中未声明为虚的，故p<span class="token operator">-&gt;</span><span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">const</span> 『根据指针类型』<span class="token punctuation">(</span>A<span class="token punctuation">)</span>调用<span class="token class-name">A</span><span class="token operator">::</span><span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">const</span>，此时编译器对非虚方法使用静态联编，输出<span class="token class-name">A</span><span class="token operator">::</span><span class="token function">f</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">const</span>。
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br></div></div><h2 id="_04-构造函数（ctor）和析构函数（dtor）相关⭐️"><a href="#_04-构造函数（ctor）和析构函数（dtor）相关⭐️" class="header-anchor">#</a> 04.构造函数（ctor）和析构函数（dtor）相关⭐️</h2> <h3 id="_4-1-c-构造函数和析构函数可以是虚函数嘛？"><a href="#_4-1-c-构造函数和析构函数可以是虚函数嘛？" class="header-anchor">#</a> 4.1.C++ 构造函数和析构函数可以是虚函数嘛？</h3> <ul><li>构造函数<strong>不可以</strong>是虚函数</li></ul> <p>因为虚函数只有和类的对象结合才能体现多态性，<strong>构造函数被调用时，类对象还没有完成建立</strong>，所以无意义。</p> <ul><li>析构函数<strong>可以且常常</strong>是虚函数</li></ul> <p>在多个派生类中如果动态分配了内存，虚析构函数可以分别释放。不然有可能造成内存泄漏。</p> <p>虚析构函数是为了解决：基类的指针指向派生类对象，并用基类的指针删除派生类对象。</p> <blockquote><p>参考自：《面向对象技术与Visual C++学习指导》，甘玲， 邱劲，张璞</p></blockquote> <h3 id="_4-2-构造函数中调用虚函数会怎么样？"><a href="#_4-2-构造函数中调用虚函数会怎么样？" class="header-anchor">#</a> 4.2.构造函数中调用虚函数会怎么样？</h3> <blockquote><p>参考：<a href="https://www.huaweicloud.com/articles/ce10c517a25e175c5ab5d0c751c0319c.html" target="_blank" rel="noopener noreferrer">华为云博客：构造函数和析构函数中可以调用调用虚函数吗<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></p></blockquote> <p>１.　从语法上讲，调用完全没有问题。
２.　但是从效果上看，往往不能达到需要的目的。</p> <ul><li>《Effective C++ 》条款9：永远不要在构造函数或析构函数中调用虚函数</li></ul> <p>为什么不能在析构和构造函数中调用呢,实际上这样做是不会报错的(试过了),但是不建议这样用</p> <p>书上,其实就是作者告诉你<strong>构造函数和析构函数中调用虚函数不会呈现出多态</strong></p> <p>因为父类对象会在子类之前进行构造，此时子类部分的数据成员还未初始化， 因此调用子类的虚函数是不安全的，故而C++不会进行动态联编。</p> <h3 id="_4-3-析构函数中调用虚函数会怎么样？"><a href="#_4-3-析构函数中调用虚函数会怎么样？" class="header-anchor">#</a> 4.3.析构函数中调用虚函数会怎么样？</h3> <p>不要在析构函数中调用虚函数的原因：析构函数是用来销毁一个对象的，在销毁一个对象时，先调用子类的析构函数，然后再调用基类的析构函数。所以<strong>在调用基类的析构函数时，派生类对象的数据成员已经“销毁”，这个时再调用子类的虚函数已经没有意义了</strong>。</p> <h2 id="⭐️04-『运算符重载』详解"><a href="#⭐️04-『运算符重载』详解" class="header-anchor">#</a> ⭐️04.『运算符重载』详解</h2> <blockquote><p>（本质还是函数重载）</p></blockquote> <h3 id="_4-1-重载的2种函数类型"><a href="#_4-1-重载的2种函数类型" class="header-anchor">#</a> 4.1.重载的2种函数类型</h3> <ul><li>1、成员函数</li> <li>2、友元函数『属于，非成员函数』</li></ul> <blockquote><p>易错：有的运算符，只能重载为『成员函数』</p></blockquote> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token operator">=</span> 			
<span class="token punctuation">[</span><span class="token punctuation">]</span>			<span class="token comment">//重载，下标运算符，比如重载后，返回当前vetor中的元素，需要this指针，而非成员函数是没有this指针的233</span>
<span class="token punctuation">(</span><span class="token punctuation">)</span>			<span class="token comment">//重载，函数调用运算符，</span>
<span class="token operator">-&gt;</span>
上面<span class="token number">4</span>个，『只能』通过成员函数进行重载
我的理解，备注如上
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><h3 id="_4-2-可以重载，但建议不要重载的运算符"><a href="#_4-2-可以重载，但建议不要重载的运算符" class="header-anchor">#</a> 4.2.可以重载，但建议不要重载的运算符</h3> <ul><li><code>&amp;&amp;</code>和<code>||</code>很建议不要重载『会出点问题』</li></ul> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code><span class="token number">1</span>、因为，重载运算符，也就意味着靠函数重载来完成，操作数会作为『函数参数，传递』
<span class="token number">2</span>、C<span class="token operator">++</span>的『函数参数都会被求值，无法实现（短路规则）』
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br></div></div><h3 id="_4-3-不能重载的5个运算符记忆"><a href="#_4-3-不能重载的5个运算符记忆" class="header-anchor">#</a> 4.3.不能重载的5个运算符记忆</h3> <ul><li><p>百度招聘考过。</p></li> <li><p>1、第1个，也是我们常常忘记是运算符的<code>sizeof</code></p></li> <li><p>2、其他4个，记住只要挂<code>.</code>的运算符<strong>均不能被重载</strong></p></li></ul> <blockquote><p>第2点，参考自用户讨论：@<a href="https://www.nowcoder.com/profile/2887214" target="_blank" rel="noopener noreferrer">牛客2887214号<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></p></blockquote> <div class="language-cpp line-numbers-mode"><pre class="language-cpp"><code>C<span class="token operator">++</span>不能重载的总共五个：
（<span class="token number">1</span>）<span class="token string">&quot;.&quot;</span>（类成员访问运算符） 
（<span class="token number">2</span>）<span class="token string">&quot; .*&quot;</span>（类成员指针访问运算符） 
（<span class="token number">3</span>）<span class="token string">&quot;::&quot;</span>（域运算符） 
（<span class="token number">4</span>）<span class="token string">&quot;siezof&quot;</span>（长度运算符） 
（<span class="token number">5</span>）<span class="token string">&quot; ?:&quot;</span>（条件运算符）
</code></pre> <div class="line-numbers-wrapper"><span class="line-number">1</span><br><span class="line-number">2</span><br><span class="line-number">3</span><br><span class="line-number">4</span><br><span class="line-number">5</span><br><span class="line-number">6</span><br></div></div><h2 id="⭐️05-c-中『栈』和『堆』"><a href="#⭐️05-c-中『栈』和『堆』" class="header-anchor">#</a> ⭐️05.C++中『栈』和『堆』</h2> <ul><li>源代码的重要性+编译器底层理解的重要性！</li></ul> <blockquote><p>（1）如何定义1个『只能』在『堆』上生成对象的类？</p></blockquote> <ul><li>在C++中，为了让某个类只能通过new来创建（即如果直接创建对象，编译器将报错），应该（）</li> <li>将『析构函数』设为『私有』</li> <li>原因：C++是静态</li></ul> <blockquote><p>（2）如何定义1个『只能』在『栈』上生成对象的类？</p></blockquote> <ul><li>将new和delete重载为『私有』</li> <li>原因：在堆上生成对象，使用new关键字操作。看过源代码知道过程是2步！！</li> <li>1、使用operator new在『堆』上找可用的内存，分配给对象</li> <li>2、调用构造函数生成对象</li> <li>所以，如果将new操作设置为『私有』，那么第1阶段就不能完成。『就不能在堆上生成对象』</li></ul> <h2 id="✅杂谈"><a href="#✅杂谈" class="header-anchor">#</a> ✅杂谈</h2> <h3 id="_01-常量表达式"><a href="#_01-常量表达式" class="header-anchor">#</a> 01.常量表达式</h3> <ul><li>《<a href="https://www.nowcoder.com/test/question/done?tid=43575799&qid=67992" target="_blank" rel="noopener noreferrer">C++Primer<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>》</li></ul> <h3 id="_02-c-98关键字"><a href="#_02-c-98关键字" class="header-anchor">#</a> 02.C++98关键字</h3> <ul><li><p>1、<code>static</code></p> <ul><li><p>修改变量或函数存储的形式，比如<code>.data</code>，<code>.bss</code></p></li> <li><p>作用是：穿透作用域、『C++ primer PXX好像是这么说的』</p></li> <li><p>参考：牛客网：<a href="https://www.nowcoder.com/test/question/done?tid=44308658&qid=14302#summary" target="_blank" rel="noopener noreferrer">关于static用途说法正确的是<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>？</p></li></ul></li> <li><p>2、<code>const</code></p> <ul><li>修改变量or函数的只读方式</li></ul></li> <li><p>3、<code>inline</code></p></li> <li><p>建议在“编译期”，直接将整个函数的代码插入调用语句处</p></li> <li><p>4、<code>friend</code></p> <ul><li>声明友元，包括，友元函数，友元类</li></ul></li></ul></div> <div class="page-edit"><!----> <!----></div> <!----> </div> <!----></div></div>
    <script src="/assets/js/app.c70e21ad.js" defer></script><script src="/assets/js/2.570d8a23.js" defer></script>
  </body>
</html>
